package cn.eleven.gui;

import cn.eleven.entity.Room;
import cn.eleven.entity.User;
import cn.eleven.service.RoomService;
import cn.eleven.service.UserService;

import javax.swing.*;
import java.awt.*;
import java.sql.SQLException;

/**
 * 房间预订界面
 */
public class RoomBookingUI extends JPanel {
    private final RoomService roomService = new RoomService();
    private final UserService userService = new UserService();
    private final int currentUserId; // 当前用户ID
    private final String currentUsername; // 当前用户的用户名
    private String occupiedRoomName; // 当前用户入住的房间名

    // 初始化当前用户信息并加载入住状态
    public RoomBookingUI(int currentUserId, String currentUsername) throws SQLException {
        this.currentUserId = currentUserId;
        this.currentUsername = currentUsername;
        loadUserRoomOccupied();  // 初始化时加载当前用户的房间入住情况
        initializeUI(); // 初始化界面
    }

    /**
     * 查询当前用户的入住房间信息
     */
    private void loadUserRoomOccupied() throws SQLException {
        User user = userService.findUserById(currentUserId);
        this.occupiedRoomName = user.getRoomOccupied(); // 记录当前入住的房间名
    }

    /**
     * 初始化界面布局
     */
    private void initializeUI() throws SQLException {
        setLayout(new BorderLayout()); // 设置布局为边界布局
        refreshRoomPanel(); // 刷新房间面板

        // 添加充值按钮
        JButton rechargeButton = new JButton("充值");
        rechargeButton.setFont(new Font("微软雅黑", Font.BOLD, 14));
        rechargeButton.addActionListener(e -> {
            SwingUtilities.invokeLater(() -> {
                try {
                    new RechargeUI(currentUserId).setVisible(true);
                } catch (SQLException ex) {
                    JOptionPane.showMessageDialog(this, "无法打开充值界面：" + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
                }
            });
        });

        JPanel bottomPanel = new JPanel();
        bottomPanel.add(rechargeButton);
        add(bottomPanel, BorderLayout.SOUTH);
    }

    /**
     * 刷新房间面板，重新加载房间信息
     */
    private void refreshRoomPanel() throws SQLException {
        removeAll(); // 清空面板上的所有组件
        loadUserRoomOccupied(); // 每次刷新都重新加载用户入住状态（防止数据过期）

        JPanel roomPanel = new JPanel(new GridLayout(0, 3, 10, 10)); // 创建一个网格布局的面板，用于展示房间信息
        roomService.getAllRooms().forEach(room -> {
            roomPanel.add(createRoomCard(room)); // 遍历所有房间并添加卡片显示
        });

        JScrollPane scrollPane = new JScrollPane(roomPanel); // 创建滚动面板
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); // 始终显示垂直滚动条
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); // 禁用水平滚动条

        add(scrollPane, BorderLayout.CENTER); // 将滚动面板添加到主面板的中心

        revalidate(); // 重新验证布局
        repaint(); // 重新绘制界面
    }

    /**
     * 创建一个房间卡片，显示房间的基本信息和操作按钮
     */
    private JPanel createRoomCard(Room room) {
        // 创建一个带有边距的卡片面板
        JPanel card = new JPanel(new BorderLayout(10, 10));
        card.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createLineBorder(Color.GRAY, 1), // 添加边框
                BorderFactory.createEmptyBorder(10, 10, 10, 10) // 添加空白内边距
        ));
        // 创建一个标签显示房间名称
        JLabel nameLabel = new JLabel(room.getName(), JLabel.CENTER);
        nameLabel.setFont(new Font("微软雅黑", Font.BOLD, 14)); // 设置字体样式
        card.add(nameLabel, BorderLayout.NORTH); // 将房间名称添加到卡片的顶部

        JPanel infoPanel = new JPanel(new GridLayout(2, 1, 5, 5)); // 创建信息面板，显示房间状态和剩余可预订人数
        infoPanel.add(new JLabel("状态：" + convertStatus(room.getStatus()))); // 添加房间状态
        infoPanel.add(new JLabel("预订金额：" + room.getPrice() + "元")); // 添加房间状态
        infoPanel.add(new JLabel("剩余可预订人数：" + room.getCapacity())); // 添加可预订人数
        card.add(infoPanel, BorderLayout.CENTER); // 将信息面板添加到卡片的中部

        JButton btn = new JButton(); // 创建一个按钮用于操作预订或退订房间

        // 判断按钮显示逻辑
        if (occupiedRoomName != null && !occupiedRoomName.isEmpty()) {
            // 用户已入住
            if (room.getName().equals(occupiedRoomName)) {
                // 当前房间是用户住的房间，显示退订
                btn.setText("退订房间");
                btn.setBackground(new Color(244, 67, 54)); // 设置退订按钮的背景色
                btn.addActionListener(e -> handleReturn(room.getId())); // 设置退订按钮的点击事件
            } else {
                // 不是用户住的房间，禁用按钮
                btn.setText("不可预订");
                btn.setEnabled(false); // 禁用按钮
                btn.setBackground(Color.LIGHT_GRAY); // 设置按钮的背景色为灰色
            }
        } else {
            // 用户未入住任何房间
            if ("AVAILABLE".equals(room.getStatus()) && room.getCapacity() > 0) {
                btn.setText("立即预订");
                btn.setBackground(new Color(76, 175, 80)); // 设置预订按钮的背景色
                btn.setEnabled(true);  // 确保按钮是可用的
                btn.addActionListener(e -> {
                    try {
                        handleRent(room.getId(), room.getName()); // 点击按钮时预订房间
                    } catch (SQLException ex) {
                        throw new RuntimeException(ex);
                    }
                });
            } else if ("OCCUPIED".equals(room.getStatus())) {
                btn.setText("房间已满");
                btn.setEnabled(false); // 禁用按钮
                btn.setBackground(Color.LIGHT_GRAY); // 设置按钮背景为灰色
            } else if ("MAINTENANCE".equals(room.getStatus())) {
                btn.setText("维护中");
                btn.setEnabled(false); // 禁用按钮
                btn.setBackground(Color.LIGHT_GRAY); // 设置按钮背景为灰色
            } else if ("CLOSED".equals(room.getStatus())) {
                btn.setText("房间关闭");
                btn.setEnabled(true); // 启用按钮
                btn.setBackground(Color.LIGHT_GRAY); // 设置按钮背景为灰色
            }
        }

        card.add(btn, BorderLayout.SOUTH); // 将按钮添加到卡片的底部
        return card; // 返回创建的房间卡片
    }


    /**
     * 预订房间
     */
    private void handleRent(int roomId, String roomName) throws SQLException {
        int confirm = JOptionPane.showConfirmDialog(this, "确认要预订该房间吗？", "确认预订", JOptionPane.YES_NO_OPTION);
        if (confirm == JOptionPane.YES_OPTION) {
            int roomPrice = roomService.getRoomPrice(roomId); // 获取房间价格

            if (User.currentBalance >= roomPrice) { // 检查余额是否足够
                if (roomService.rentRoom(roomId, currentUserId)) {
                    userService.updateRoomOccupied(currentUserId, roomName); // 更新用户 room_occupied 字段
                    userService.deductBalance(currentUserId, roomPrice); // 扣减余额
                    User.currentBalance -= roomPrice; // 更新内存中的余额
                    JOptionPane.showMessageDialog(this, "预订成功！"); // 弹出预订成功的提示框
                    refreshRoomPanel(); // 刷新房间面板
                } else {
                    JOptionPane.showMessageDialog(this, "操作失败，请重试！", "错误", JOptionPane.ERROR_MESSAGE); // 弹出错误提示框
                }
            } else {
                JOptionPane.showMessageDialog(this, "余额不足，无法预订该房间！", "错误", JOptionPane.ERROR_MESSAGE);
            }
        }
    }


    /**
     * 退订房间
     */
    private void handleReturn(int roomId) {
        int confirm = JOptionPane.showConfirmDialog(this, "确认要退订该房间吗？", "确认退订", JOptionPane.YES_NO_OPTION);
        if (confirm == JOptionPane.YES_OPTION) {
            if (roomService.returnRoom(roomId, currentUserId)) {
                userService.clearRoomOccupied(currentUserId); // 清空用户room_occupied字段
                SwingUtilities.invokeLater(() -> {
                    try {
                        refreshRoomPanel(); // 刷新房间面板
                        JOptionPane.showMessageDialog(this, "退订成功！"); // 弹出退订成功的提示框
                    } catch (SQLException e) {
                        throw new RuntimeException(e);
                    }
                });
            } else {
                JOptionPane.showMessageDialog(this, "操作失败，请重试！", "错误", JOptionPane.ERROR_MESSAGE); // 弹出错误提示框
            }
        }
    }

    /**
     * 房间状态渲染
     */
    private String convertStatus(String status) {
        return switch (status) {
            case "AVAILABLE" -> "空闲中";
            case "OCCUPIED" -> "已满";
            case "MAINTENANCE" -> "维护中";
            default -> "房间关闭";
        };
    }
}
